﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Security.Cryptography;
using elibrary.Classes;
using elibrary.Models.Managers;

namespace elibrary.Models.Entities
{
    public class User
    {
        /* Class Fields [Start] ----------------------------------------------------------------- */
        [Key]
        public int id { get; set; }
        public string loginId { get; set; }
        public string password { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
        public string email { get; set; }
        public DateTime dob { get; set; }
        public string secretQuestion { get; set; }
        public string secretAnswer { get; set; }
        public string contactNum { get; set; }
        public string address { get; set; }
        public char gender { get; set; }
        public bool isAdmin { get; set; }
        public bool hasUpdatedProfile { get; set; }
        public string bankName { get; set; }
        public string bankAccNum { get; set; }
        public UserStatus status { get; set; }
        /* Class Fields [End] ------------------------------------------------------------------- */

        /* Computed Fields [Start] -------------------------------------------------------------- */
        public string fullName
        {
            get { return this.firstName + " " + this.lastName; }
        }

        [NotMapped]
        public string addressStreet
        {
            get { return Utilities.pieceString(this.address, '$', 0, ""); }
            set { this.address = Utilities.setPieceString(this.address, '$', 0, value); }
        }

        [NotMapped]
        public string addressExtra
        {
            get { return Utilities.pieceString(this.address, '$', 1, ""); }
            set { this.address = Utilities.setPieceString(this.address, '$', 1, value); }
        }

        [NotMapped]
        public string addressCity
        {
            get { return Utilities.pieceString(this.address, '$', 2, ""); }
            set { this.address = Utilities.setPieceString(this.address, '$', 2, value); }
        }

        [NotMapped]
        public string addressPostcode
        {
            get { return Utilities.pieceString(this.address, '$', 3, ""); }
            set { this.address = Utilities.setPieceString(this.address, '$', 3, value); }
        }

        [NotMapped]
        public string addressState
        {
            get { return Utilities.pieceString(this.address, '$', 4, ""); }
            set { this.address = Utilities.setPieceString(this.address, '$', 4, value); }
        }

        [NotMapped]
        public string addressCountry
        {
            get { return Utilities.pieceString(this.address, '$', 5, ""); }
            set { this.address = Utilities.setPieceString(this.address, '$', 5, value); }
        }
        /* Computed Fields [End] ---------------------------------------------------------------- */

        /* Class Enums [Start] ------------------------------------------------------------------ */
        public enum UserStatus { Active = 0, Waiting, Barred }
        /* Class Enums [End] -------------------------------------------------------------------- */

        public static string descrbibeStatus(UserStatus s)
        {
            switch (s)
            {
                case UserStatus.Active:
                    return "Active";
                case UserStatus.Waiting:
                    return "Waiting";
                case UserStatus.Barred:
                    return "Barred";
                default:
                    return "-";
            }
        }

        public bool authenticate(string ipass)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                string ipassEcr = Utilities.getMd5Hash(md5Hash, ipass);

                return ipassEcr.Equals(this.password);
            }
        }

        public bool changePassword(string opass,string npass)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                string opassEcr = Utilities.getMd5Hash(md5Hash,opass);
                if (!opassEcr.Equals(this.password))
                    return false;

                this.password = Utilities.getMd5Hash(md5Hash,npass);
            }

            return true;
        }

        public string resetPassword(string answer,string email, int len)
        {
            MD5 md5Hash = MD5.Create();
            if (!Utilities.getMd5Hash(md5Hash,answer).Equals(this.secretAnswer) || 
                !email.Equals(this.email))
                return null;

            string pass = Utilities.randomizeString(len,false,true);
            this.password = Utilities.getMd5Hash(md5Hash,pass);

            return pass;
        }

    }
}